package energy;

import java.util.Arrays;
import java.util.Date;

import org.apache.log4j.Logger;

public class Counter extends AbstractDataProcessor {
	
	private static Logger log = Logger.getLogger("energy.Counter");
	
	private double[] chargeMin;
	private double[] chargeCounter;
	private double[] chargeMax;
	private double[] timeMin;
	private double[] timeCounter;
	private double[] timeMax;
	private int states;	
	private double totalTime;
	
	private EnergyData previous;
	
	public Counter(int states) {
		this.states = states+1; // add fail state 0
		chargeMin = new double[this.states];
		chargeCounter = new double[this.states];
		chargeMax = new double[this.states];
		timeMin = new double[this.states];
		timeCounter = new double[this.states];
		timeMax = new double[this.states];
		previous = null;
		//beforeStateChange = null;
	}

	@Override
	public void process(EnergyData data) {

		if(previous==null) {
			Arrays.fill(chargeMin, 0.0);
			Arrays.fill(chargeCounter, 0.0);
			Arrays.fill(chargeMax, 0.0);
			Arrays.fill(timeMin, 0.0);
			Arrays.fill(timeCounter, 0.0);
			Arrays.fill(timeMax, 0.0);
			totalTime = 0.0;
		} else {
			
			totalTime += (data.time - previous.time) / 32.768;
			
			if(data.state!=previous.state) {
				handleStateChange(data);
			} else {
				handleNormal(data);
			}
			
		}
		
		previous = data;
	}
	
	public void reset() {
		previous = null;
	}
	
	private void handleStateChange(EnergyData data) {
		double time = (data.time - previous.time) / 32.768;
		double charge = data.current * time;
		
		chargeCounter[data.state] += charge/2.0;
		chargeMin[data.state] += 0.0;
		chargeMax[data.state] += charge;
		timeCounter[data.state] += time/2.0;
		timeMin[data.state] += 0.0;
		timeMax[data.state] += time;
		
		chargeCounter[previous.state] += charge/2.0;
		chargeMin[previous.state] += 0.0;
		chargeMax[previous.state] += charge;
		timeCounter[previous.state] += time/2.0;
		timeMin[previous.state] += 0;
		timeMax[previous.state] += time;
	}
	
	private void handleNormal(EnergyData data) {
		double time = (data.time - previous.time) / 32.768;
		double charge = data.current * time;
		chargeCounter[data.state] += charge;
		chargeMin[data.state] += charge;
		chargeMax[data.state] += charge;
		timeCounter[data.state] += time;
		timeMin[data.state] += time;
		timeMax[data.state] += time;
	}
	
	public int getStates() {
		return states;
	}
	
	public double getTotalTime() {
		return totalTime;
	}
	
	public double[] getChargeCounter() {
		return chargeCounter;
	}
	
	public double[] getChargeMin() {
		return chargeMin;
	}
	
	public double[] getChargeMax() {
		return chargeMax;
	}
	
	public String getDescription() {
		String result = "\nstate;min;charge;max\n";
		for(int i=1; i<states; i++) {
			result += i + ";" + chargeMin[i] + ";" + chargeCounter[i] + ";" + chargeMax[i] + ";\n"; 
		}
		return result;
	}
	
	public String[] getHeaders() {
		String[] names = {"State", "E. Min", "E. Counter", "E. Max", "T. Min", "T. Counter", "T. Max"};
		return names;
	}
	
	public String[][] getData() {
		String[][] data = new String[states][7];
		for(int i=0; i<states; i++) {
			if(i==0) data[i][0] = "fail";
			else data[i][0] = ""+(i);
			data[i][1] = ""+chargeMin[i];
			data[i][2] = ""+chargeCounter[i];
			data[i][3] = ""+chargeMax[i];
			data[i][4] = ""+timeMin[i];
			data[i][5] = ""+timeCounter[i];
			data[i][6] = ""+timeMax[i];
		}
		return data;
	}
	
}


/*
@Override
public void process(EnergyData data) {

	if(previous==null) {
		Arrays.fill(min, 0.0);
		Arrays.fill(counters, 0.0);
		Arrays.fill(max, 0.0);
	} else {
	
		
		
		// check for state change
		if(data.state!=previous.state) {
			if(beforeStateChange==null) {
				beforeStateChange = previous;
			} else {
				beforeStateChange = null;
				handleNormal(previous);
				handleNormal(data);
			}
		}
		// no state change
		else {
			if(beforeStateChange!=null) {
				handlePreviousStateChange(data);
				beforeStateChange = null;
			} else {
				handleNormal(data);
			}
		}
	
		
		// 
		
	}
	
	previous = data;
}

private void handlePreviousStateChange(EnergyData data) {
	
}

private void handleNormal(EnergyData data) {
	double charge = data.current * (data.time - previous.time);
	counters[data.state] += charge;
	min[data.state] += charge;
	max[data.state] += charge;
}

private void setMinMax(EnergyData data) {
	
}
*/